{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1、获取大模型",
   "id": "1c9caf9f45ff0ece"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:49:13.042306Z",
     "start_time": "2025-08-21T13:49:05.622065Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#导入 dotenv 库的 load_dotenv 函数，用于加载环境变量文件（.env）中的配置\n",
    "import dotenv\n",
    "from langchain_openai import ChatOpenAI\n",
    "import os\n",
    "\n",
    "dotenv.load_dotenv()  #加载当前目录下的 .env 文件\n",
    "\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY1\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "# 创建大模型实例\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\")  # 默认使用 gpt-3.5-turbo\n",
    "\n",
    "# 直接提供问题，并调用llm\n",
    "response = llm.invoke(\"什么是大模型？\")\n",
    "print(response)"
   ],
   "id": "ce788165255a6aee",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='大模型通常指的是规模庞大、参数众多的机器学习模型，尤其是在自然语言处理（NLP）和计算机视觉等领域。它们有几个显著的特点：\\n\\n1. **参数量大**：大模型通常拥有数亿到数百亿的参数，使得它们能够捕捉复杂的模式和特征。\\n\\n2. **深度学习架构**：大模型通常采用深度学习技术，使用多层神经网络来处理和理解数据。\\n\\n3. **数据需求**：为了有效训练大模型，需要大量的数据集。这些数据通常是多样化的，以帮助模型更好地泛化。\\n\\n4. **计算资源**：训练和运行大模型需要大量的计算资源，通常需要使用高性能的图形处理单元（GPU）或专用的机器学习硬件（比如TPU）。\\n\\n5. **应用广泛**：大模型在许多应用场景中表现出色，包括文本生成（如GPT-3）、图像识别、翻译、对话系统等。\\n\\n6. **迁移学习**：大模型通常可以通过迁移学习的方式进行微调，使其适应特定任务，这样可以在较小数据集上取得良好的效果。\\n\\n这些大模型在推动人工智能（AI）和机器学习（ML）技术的发展中发挥了重要作用，但它们也带来了成本、能耗和伦理等方面的挑战。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 313, 'prompt_tokens': 12, 'total_tokens': 325, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_efad92c60b', 'id': 'chatcmpl-C6zx5a26u5W9NLhNyV59W39FjpGvA', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None} id='run--8d31ea60-bd43-4138-b09b-df1d399be241-0' usage_metadata={'input_tokens': 12, 'output_tokens': 313, 'total_tokens': 325, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 2、使用提示词模板",
   "id": "dd908d3010884a30"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:50:29.883037Z",
     "start_time": "2025-08-21T13:50:21.403902Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "# 需要注意的一点是，这里需要指明具体的role，在这里是system和用户\n",
    "prompt = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是世界级的技术文档编写者\"),\n",
    "    (\"user\", \"{input}\")  # {input}为变量\n",
    "])\n",
    "\n",
    "# 我们可以把prompt和具体llm的调用和在一起。\n",
    "chain = prompt | llm\n",
    "message = chain.invoke({\"input\": \"大模型中的LangChain是什么?\"})\n",
    "print(message)\n",
    "\n",
    "# print(type(message))"
   ],
   "id": "3540706aaa244853",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='LangChain是一个用于构建与大语言模型（如OpenAI的GPT系列、Google的BERT等）交互的应用程序的框架和工具集。它旨在简化和加速开发过程，使开发者能够更高效地创建、管理和集成基于语言模型的应用。LangChain的主要特点和功能包括：\\n\\n1. **组件化架构**：LangChain提供了一系列模块和组件，例如数据加载器、模型接口、链式调用等，这些组件可以根据需要组合使用，以实现复杂的应用逻辑。\\n\\n2. **多模型支持**：LangChain支持多种语言模型提供商，允许开发者选择最适合其应用需求的模型。\\n\\n3. **上下文管理**：LangChain能够管理对话和上下文，使得与用户的交互更加自然和连贯。\\n\\n4. **数据集成**：LangChain可以与各种数据源（如数据库、API、文件系统等）集成，以便从中提取和处理数据。\\n\\n5. **可扩展性**：开发者可以根据自己的需求扩展LangChain的功能，添加自定义组件和逻辑，以满足特定的业务场景。\\n\\n6. **社区和文档支持**：LangChain拥有活跃的社区和丰富的文档资料，方便开发者查找示例和进行技术交流。\\n\\n通过使用LangChain，开发者可以更容易地构建复杂的自然语言处理（NLP）应用，如聊天机器人、问答系统、内容生成工具等，从而加速产品的开发周期并提高项目的成功率。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 345, 'prompt_tokens': 29, 'total_tokens': 374, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_efad92c60b', 'id': 'chatcmpl-C6zyI6h69ztxtP5eP3TaKya1MY2DJ', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None} id='run--08a8fbcc-2e53-4415-b69a-4150140be0a8-0' usage_metadata={'input_tokens': 29, 'output_tokens': 345, 'total_tokens': 374, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 3、 使用输出解析器",
   "id": "7636c01962fa0c2e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:51:18.550994Z",
     "start_time": "2025-08-21T13:51:16.084164Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_core.output_parsers import StrOutputParser,JsonOutputParser\n",
    "\n",
    "# 初始化模型\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "# 创建提示模板\n",
    "prompt = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是世界级的技术文档编写者。\"),\n",
    "    (\"user\", \"{input}\")\n",
    "])\n",
    "\n",
    "# 使用输出解析器\n",
    "# output_parser = StrOutputParser()\n",
    "output_parser = JsonOutputParser()\n",
    "\n",
    "# 将其添加到上一个链中\n",
    "# chain = prompt | llm\n",
    "chain = prompt | llm | output_parser\n",
    "\n",
    "# 调用它并提出同样的问题。答案是一个字符串，而不是ChatMessage\n",
    "# chain.invoke({\"input\": \"LangChain是什么?\"})\n",
    "chain.invoke({\"input\": \"LangChain是什么? 用JSON格式回复，问题用question，回答用answer\"})"
   ],
   "id": "23406024ea864619",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question': 'LangChain是什么?',\n",
       " 'answer': 'LangChain是一个用于构建基于大语言模型（LLM）应用程序的框架。它提供了多个模块和工具，使开发人员能够创建复杂的应用，如对话式代理、问答系统和文本生成工具。LangChain支持与多种LLM和数据源的连接，使得编写、调试和部署基于语言模型的应用变得更加高效。'}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 4、使用向量存储",
   "id": "152461370a49413f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:53:08.453078Z",
     "start_time": "2025-08-21T13:52:40.823449Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 导入和使用 WebBaseLoader\n",
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "import bs4\n",
    "\n",
    "loader = WebBaseLoader(\n",
    "        web_path=\"https://www.gov.cn/xinwen/2020-06/01/content_5516649.htm\",\n",
    "        bs_kwargs=dict(parse_only=bs4.SoupStrainer(id=\"UCAP-CONTENT\"))\n",
    "    )\n",
    "docs = loader.load()\n",
    "# print(docs)\n",
    "\n",
    "# 对于嵌入模型，这里通过 API调用\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "\n",
    "embeddings = OpenAIEmbeddings(model=\"text-embedding-ada-002\")\n",
    "\n",
    "\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "\n",
    "# 使用分割器分割文档\n",
    "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)\n",
    "documents = text_splitter.split_documents(docs)\n",
    "print(len(documents))\n",
    "# 向量存储  embeddings 会将 documents 中的每个文本片段转换为向量，并将这些向量存储在 FAISS 向量数据库中\n",
    "vector = FAISS.from_documents(documents, embeddings)"
   ],
   "id": "c182765067f9f4eb",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "USER_AGENT environment variable not set, consider setting it to identify your requests.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "248\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 5、RAG(检索增强生成)",
   "id": "795b38c85dfb39fe"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:54:32.319977Z",
     "start_time": "2025-08-21T13:54:25.549076Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import PromptTemplate\n",
    "\n",
    "retriever = vector.as_retriever()\n",
    "retriever.search_kwargs = {\"k\": 3}\n",
    "docs = retriever.invoke(\"建设用地使用权是什么？\")\n",
    "\n",
    "# for i,doc in enumerate(docs):\n",
    "#     print(f\"⭐第{i+1}条规定：\")\n",
    "#     print(doc)\n",
    "\n",
    "# 6.定义提示词模版\n",
    "prompt_template = \"\"\"\n",
    "你是一个问答机器人。\n",
    "你的任务是根据下述给定的已知信息回答用户问题。\n",
    "确保你的回复完全依据下述已知信息。不要编造答案。\n",
    "如果下述已知信息不足以回答用户的问题，请直接回复\"我无法回答您的问题\"。\n",
    "\n",
    "已知信息:\n",
    "{info}\n",
    "\n",
    "用户问：\n",
    "{question}\n",
    "\n",
    "请用中文回答用户问题。\n",
    "\"\"\"\n",
    "# 7.得到提示词模版对象\n",
    "template = PromptTemplate.from_template(prompt_template)\n",
    "\n",
    "# 8.得到提示词对象\n",
    "prompt = template.format(info=docs, question='建设用地使用权是什么？')\n",
    "\n",
    "## 9. 调用LLM\n",
    "response = llm.invoke(prompt)\n",
    "print(response.content)"
   ],
   "id": "dcfa2c4bd0704d50",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "建设用地使用权是指依法设立的，允许使用特定土地进行建设的权利。根据相关规定，建设用地使用权可以在土地的地表、地上或者地下设立，并可以通过出让或划拨等方式取得。建设用地使用权人有权根据法律和合同的约定使用、转让、抵押等该土地，并且在建筑物、构筑物及其附属设施的所有权归属上，建设用地使用权人享有相应的权利。\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 6、使用Agent",
   "id": "d9feeb62844c3439"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-21T13:56:14.407134Z",
     "start_time": "2025-08-21T13:56:03.168429Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.tools.retriever import create_retriever_tool\n",
    "\n",
    "# 检索器工具\n",
    "retriever_tool = create_retriever_tool(\n",
    "    retriever,\n",
    "    \"CivilCodeRetriever\",\n",
    "    \"搜索有关中华人民共和国民法典的信息。关于中华人民共和国民法典的任何问题，您必须使用此工具!\",\n",
    ")\n",
    "\n",
    "tools = [retriever_tool]\n",
    "\n",
    "from langchain import hub\n",
    "from langchain.agents import create_openai_functions_agent\n",
    "from langchain.agents import AgentExecutor\n",
    "\n",
    "# https://smith.langchain.com/hub\n",
    "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
    "\n",
    "agent = create_openai_functions_agent(llm, tools, prompt)\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\n",
    "\n",
    "# 运行代理\n",
    "agent_executor.invoke({\"input\": \"建设用地使用权是什么\"})"
   ],
   "id": "26eb95f11df6bc53",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\developTools\\miniconda3\\envs\\pyth310\\lib\\site-packages\\langsmith\\client.py:272: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `CivilCodeRetriever` with `{'query': '建设用地使用权'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[36;1m\u001B[1;3m第三百四十五条　建设用地使用权可以在土地的地表、地上或者地下分别设立。\n",
      "第三百四十六条　设立建设用地使用权，应当符合节约资源、保护生态环境的要求，遵守法律、行政法规关于土地用途的规定，不得损害已经设立的用益物权。\n",
      "第三百四十七条　设立建设用地使用权，可以采取出让或者划拨等方式。\n",
      "工业、商业、旅游、娱乐和商品住宅等经营性用地以及同一土地有两个以上意向用地者的，应当采取招标、拍卖等公开竞价的方式出让。\n",
      "严格限制以划拨方式设立建设用地使用权。\n",
      "第三百四十八条　通过招标、拍卖、协议等出让方式设立建设用地使用权的，当事人应当采用书面形式订立建设用地使用权出让合同。\n",
      "建设用地使用权出让合同一般包括下列条款：\n",
      "（一）当事人的名称和住所；\n",
      "（二）土地界址、面积等；\n",
      "（三）建筑物、构筑物及其附属设施占用的空间；\n",
      "（四）土地用途、规划条件；\n",
      "（五）建设用地使用权期限；\n",
      "（六）出让金等费用及其支付方式；\n",
      "（七）解决争议的方法。\n",
      "第三百四十九条　设立建设用地使用权的，应当向登记机构申请建设用地使用权登记。建设用地使用权自登记时设立。登记机构应当向建设用地使用权人发放权属证书。\n",
      "\n",
      "第三百五十条　建设用地使用权人应当合理利用土地，不得改变土地用途；需要改变土地用途的，应当依法经有关行政主管部门批准。\n",
      "第三百五十一条　建设用地使用权人应当依照法律规定以及合同约定支付出让金等费用。\n",
      "第三百五十二条　建设用地使用权人建造的建筑物、构筑物及其附属设施的所有权属于建设用地使用权人，但是有相反证据证明的除外。\n",
      "第三百五十三条　建设用地使用权人有权将建设用地使用权转让、互换、出资、赠与或者抵押，但是法律另有规定的除外。\n",
      "第三百五十四条　建设用地使用权转让、互换、出资、赠与或者抵押的，当事人应当采用书面形式订立相应的合同。使用期限由当事人约定，但是不得超过建设用地使用权的剩余期限。\n",
      "第三百五十五条　建设用地使用权转让、互换、出资或者赠与的，应当向登记机构申请变更登记。\n",
      "第三百五十六条　建设用地使用权转让、互换、出资或者赠与的，附着于该土地上的建筑物、构筑物及其附属设施一并处分。\n",
      "第三百五十七条　建筑物、构筑物及其附属设施转让、互换、出资或者赠与的，该建筑物、构筑物及其附属设施占用范围内的建设用地使用权一并处分。\n",
      "\n",
      "第三百五十八条　建设用地使用权期限届满前，因公共利益需要提前收回该土地的，应当依据本法第二百四十三条的规定对该土地上的房屋以及其他不动产给予补偿，并退还相应的出让金。\n",
      "第三百五十九条　住宅建设用地使用权期限届满的，自动续期。续期费用的缴纳或者减免，依照法律、行政法规的规定办理。\n",
      "非住宅建设用地使用权期限届满后的续期，依照法律规定办理。该土地上的房屋以及其他不动产的归属，有约定的，按照约定；没有约定或者约定不明确的，依照法律、行政法规的规定办理。\n",
      "第三百六十条　建设用地使用权消灭的，出让人应当及时办理注销登记。登记机构应当收回权属证书。\n",
      "第三百六十一条　集体所有的土地作为建设用地的，应当依照土地管理的法律规定办理。\n",
      "第十三章　宅基地使用权\n",
      "第三百六十二条　宅基地使用权人依法对集体所有的土地享有占有和使用的权利，有权依法利用该土地建造住宅及其附属设施。\n",
      "第三百六十三条　宅基地使用权的取得、行使和转让，适用土地管理的法律和国家有关规定。\n",
      "第三百六十四条　宅基地因自然灾害等原因灭失的，宅基地使用权消灭。对失去宅基地的村民，应当依法重新分配宅基地。\u001B[0m\u001B[32;1m\u001B[1;3m建设用地使用权是指由国家或集体出让或划拨给使用者在一定期间内对特定土地进行建设、开发和利用的权利。根据中华人民共和国民法典的相关规定，建设用地使用权的具体内容包括：\n",
      "\n",
      "1. **设立方式**：建设用地使用权可以通过出让或划拨的方式设立，且出让方式一般使用公开招标、拍卖等方式，特别是对于经营性用地。\n",
      "\n",
      "2. **合同内容**：建设用地使用权出让合同应包含当事人的信息、土地界址、面积、用途、使用权期限、出让金等费用及解决争议的方法。\n",
      "\n",
      "3. **登记**：建设用地使用权需向登记机构申请登记，登记后方可正式设立，并会发放权属证书。\n",
      "\n",
      "4. **合理利用和用途变更**：使用权人应合理利用土地，不得擅自改变土地用途，如需变更需经过相关行政部门的批准。\n",
      "\n",
      "5. **转让和抵押**：建设用地使用权人有权转让、出资、赠与或抵押该使用权，但需遵守法律规定。\n",
      "\n",
      "6. **使用权期限**：住宅建设用地使用权在期限届满后可以自动续期，而非住宅用地的续期则需依法办理。\n",
      "\n",
      "7. **补偿机制**：如因公共利益需要收回土地，建设用地使用权人有权获得相应的补偿。\n",
      "\n",
      "上述内容为建设用地使用权的基本信息和法律规定。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': '建设用地使用权是什么',\n",
       " 'output': '建设用地使用权是指由国家或集体出让或划拨给使用者在一定期间内对特定土地进行建设、开发和利用的权利。根据中华人民共和国民法典的相关规定，建设用地使用权的具体内容包括：\\n\\n1. **设立方式**：建设用地使用权可以通过出让或划拨的方式设立，且出让方式一般使用公开招标、拍卖等方式，特别是对于经营性用地。\\n\\n2. **合同内容**：建设用地使用权出让合同应包含当事人的信息、土地界址、面积、用途、使用权期限、出让金等费用及解决争议的方法。\\n\\n3. **登记**：建设用地使用权需向登记机构申请登记，登记后方可正式设立，并会发放权属证书。\\n\\n4. **合理利用和用途变更**：使用权人应合理利用土地，不得擅自改变土地用途，如需变更需经过相关行政部门的批准。\\n\\n5. **转让和抵押**：建设用地使用权人有权转让、出资、赠与或抵押该使用权，但需遵守法律规定。\\n\\n6. **使用权期限**：住宅建设用地使用权在期限届满后可以自动续期，而非住宅用地的续期则需依法办理。\\n\\n7. **补偿机制**：如因公共利益需要收回土地，建设用地使用权人有权获得相应的补偿。\\n\\n上述内容为建设用地使用权的基本信息和法律规定。'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
